<template>
  <!-- 
        此组件只解决单张图片上传
        1、添加图片上传时呈现出 loading 的一个状态
        2、添加在图片上传完成后，鼠标放在图片上呈现出 “图片预览”、“删除图片” 的效果
        3、自定义图片大小以及方形圆形图片
     -->
  <div class="l-upload" :class="round ? 'round' : ''">
    <!-- el-upload 组件 -->
    <el-upload
      class="avatar-uploader"
      :style="uploadStyle"
      :headers="headers"
      :action="action"
      :show-file-list="false"
      :on-success="handleAvatarSuccess"
      :before-upload="beforeAvatarUpload"
      :on-progress="handleAvatarProgress"
      v-loading="uploadLoading"
    >
      <div class="avatar" v-if="modelValue" @click.stop>
        <el-image class="image" :src="modelValue" ref="imageRef" />
        <!-- 鼠标 hover 是图片上方遮罩层 -->
        <div class="el-upload-actions">
          <!-- 图片预览ICON -->
          <div class="item" @click="handlePictureCardPreview">
            <el-icon size="18" color="#fff">
              <ZoomIn />
            </el-icon>
          </div>
          <!-- 图片删除ICON -->
          <div class="item" @click="handleRemove">
            <el-icon size="18" color="#fff">
              <Delete />
            </el-icon>
          </div>
        </div>
      </div>
      <el-icon v-else class="avatar-uploader-icon">
        <Plus />
      </el-icon>
    </el-upload>
    <!-- 实现图片大图预览 -->
    <!-- 注意 ElImageViewer 组件必须要使用v-if判断 -->
    <ElImageViewer
      v-if="isImageView"
      :url-list="srcList"
      @close="imageClose"
    ></ElImageViewer>
  </div>
</template>

<script setup lang="ts">
import { defineProps, reactive, ref, toRefs, defineEmits } from "vue";
import { Plus, ZoomIn, Delete } from "@element-plus/icons-vue"; // 引入 Element 中的图标
import { ElImageViewer } from "element-plus"; // 实现图片预览的组件,注意这是 element-plus 中的哦

// import { getDomainName } from "@/utils/index"; // 获取 域名地址
// import Cookies from "js-cookie";

const props = defineProps({
  // 父组件 v-model 绑定的值
  modelValue: {
    type: String,
  },
  // 图片上传时的地址
  action: {
    type: String,
    default: "http://127.0.0.1:1024/image/upload",
  },
  // 定义 el-upload 组件的样式
  uploadStyle: {
    type: Object,
    default: {
      width: "200px",
      height: "200px",
    },
  },
  // 图片是否为圆形
  round: {
    type: Boolean,
    default: false,
  },
});

const state = reactive({
  uploadLoading: false, // 图片文件大时 呈现出一个上传中的loading状态
  headers: {
    // el-upload 自定义 headers 头（根据自己的接口看是否需要）
    Authorization: Cookies.get("Token"),
    ContentType: "application/json;charset=utf-8",
  },
  isImageView: false, // 图片预览时的状态
  srcList: [] as any, // 图片预览列表（可以是多张）
});

const { headers, uploadLoading, isImageView, srcList } = toRefs(state);
const imageRef = ref();

const emit = defineEmits(["update:modelValue"]);

// 预览图片
function handlePictureCardPreview() {
  state.isImageView = true;
}

// 关闭图片预览
function imageClose() {
  state.isImageView = false;
  state.srcList = []; // 每次关闭图片预览时清空一下
}

// 删除图片
function handleRemove() {
  emit("update:modelValue", "");
}

// 图片上传成功
function handleAvatarSuccess(response: any, file: any, fileList: any) {
  // response 上传成功返回的数据，根据自己的情况来写。
  let url = getDomainName() + response.data.url;
  emit("update:modelValue", url);
  state.srcList.push(url);
  state.uploadLoading = false;
}
// 图片上传之前
function beforeAvatarUpload() {}

// 图片上传时
function handleAvatarProgress() {
  state.uploadLoading = true;
}
</script>

<style scoped lang="scss">
.l-upload {
  ::v-deep .el-upload {
    width: 100%;
    height: 100%;
    border: 1px dashed #dcdfe6;
  }

  .avatar-uploader {
    .avatar {
      width: 100%;
      height: 100%;
      cursor: auto;
      position: relative;

      .image {
        width: 100%;
        height: 100%;
      }

      .el-upload-actions {
        top: 0;
        left: 0;
        cursor: auto;
        width: 100%;
        height: 100%;
        transition: 0.5s;
        position: absolute;
        background: rgba($color: #000000, $alpha: 0.5);
        opacity: 0;
        display: flex;
        align-items: center;
        justify-content: center;

        .item {
          width: 30px;
          height: 30px;
          display: flex;
          cursor: pointer;
          align-items: center;
          justify-content: center;
        }
      }

      &:hover {
        .el-upload-actions {
          opacity: 1;
          display: flex;
          align-items: center;
          justify-content: center;
        }
      }
    }
  }
}

.round {
  ::v-deep .el-upload {
    border-radius: 50px;
    overflow: hidden;
  }
}
</style>
